/**
 * This file is part of Opintopaivakirja.
 *
 * Opintopaivakirja is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Opintopaivakirja is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Opintopaivakirja.  If not, see <http://www.gnu.org/licenses/>.
 */
package opintopaivakirja;

import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 * Luokka toteuttaa järjestelmän ominaisuudet, jotka liittyvät 
 * järjestelmään lisättävien linkkien hallintaan. Luokasta muodostetut
 * instassit sijoitetaan tavallisesti muistiinpanon olio-taulukkoon.
 * <p>
 * Projekti-luokan linkki-muuttuja ei käytä tätä luokkaa.
 * <p>
 * Tila-muuttuja kertoo onko projekti
 * <ul>
 * <li>(-1) poistettava
 * <li>(0) uusi
 * <li>(1) vanha
 * </ul>
 *
 * @author Teemu Jonkkari
 * @version 1.0
 */
public class Linkki {

    private int id;
    private int tila;
    private String otsikko;
    private String url;

    /**
     * Oletusmuodostin
     */
    public Linkki() {
        this.tila = 0;
    }

    /**
     * Muodostin, jolla voidaan asettaa suoraan linkin otsikko ja url.
     * 
     * @param otsikko Linkin käyttöliittymässä käytetty nimi (esim. TTY, Porin yksikkö).
     * @param url Linkin osoittama verkko- tai paikallinen osoite (esim. http://www.pori.tut.fi/).
     */
    public Linkki(String otsikko, String url) {
        this.otsikko = otsikko;
        this.url = url;
        this.tila = 0;
    }

    /**
     * Muodostin, jolla voidaan asettaa suoraan linkin id, otsikko ja url.
     * <p>
     * Tarkoitettu tietokantakyselyn käytettäväksi, sillä tällöin tiedetään
     * myös id ja voidaan asettaa se.
     * Käyttäjän tekemällä uudella linkillä ei ole id:tä ennen sen
     * kantaan tallentamista.
     *
     * @param id Linkin id-tunniste.
     * @param otsikko Linkin käyttöliittymässä käytetty nimi (esim. TTY, Porin yksikkö).
     * @param url Linkin osoittama verkko- tai paikallinen osoite (esim. http://www.pori.tut.fi/).
     * @param tila Linkin tila (poistettava (-1), uusi (0), vanha (1), muokattu (2)).
     */
    private Linkki(int id, String otsikko, String url, int tila) {
        this.id = id;
        this.otsikko = otsikko;
        this.url = url;
        this.tila = tila;
    }

    /**
     * Metodilla voidaan hakea muistiinpanon linkit tietokannasta.
     *
     * @param muistiinpanoid Muistiinpanon id, joka omistaa linkin.
     * @return ArrayList, jossa löydetyt linkit.
     */
    public ArrayList<Linkki> selectLinkit(int muistiinpanoid) {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement ps = null;

        ArrayList<Linkki> links = new ArrayList<Linkki>();

        try {
            conn = new Tietokanta().getYhteys();

            ps = conn.prepareStatement("" +
                    "SELECT ID, OTSIKKO, URL FROM OPINTOPAIVAKIRJA.LINKKI " +
                    "WHERE MUISTIINPANO_ID = ? ORDER BY OTSIKKO ASC");
            ps.setInt(1, muistiinpanoid);

            rs = ps.executeQuery();

            while (rs.next()) {
                Linkki l = new Linkki(rs.getInt("id"),
                        rs.getString("otsikko"), rs.getString("url"), 1);
                links.add(l);
            }

        } catch (SQLException ex) {
            Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
        } catch (NullPointerException e) {
            Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), e);
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                    ps = null;
                } catch (SQLException ex) {
                    Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
                }
            }

            if (rs != null) {
                try {
                    rs.close();
                    rs = null;
                } catch (SQLException ex) {
                    Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
                }
            }
            return links;
        }
    }

    /**
     * Metodilla voidaan lisätä linkki tietokantaan.
     *
     * @param muistiinpanoid Muistiinpanon id-tunniste, johon lisättävä linkki kuuluu.
     * @param linkki Linkki, jonka tiedot lisätään tietokantaan.
     * @return boolean siitä, onnistuiko linkin lisääminen tietokantaan.
     */
    public boolean insertLinkki(int muistiinpanoid, Linkki linkki) {
        Connection conn = null;
        PreparedStatement ps = null;

        boolean vastaus = true;

        try {
            conn = new Tietokanta().getYhteys();

            ps = conn.prepareStatement("" +
                    "INSERT INTO OPINTOPAIVAKIRJA.LINKKI " +
                    "(MUISTIINPANO_ID, OTSIKKO, URL) VALUES (?, ?, ?)");
            ps.setInt(1, muistiinpanoid);
            ps.setString(2, linkki.otsikko);
            ps.setString(3, linkki.url);

            ps.executeUpdate();

        } catch (SQLException ex) {
            Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
            vastaus = false;
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                    ps = null;
                } catch (SQLException ex) {
                    Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
                }
            }
            return vastaus;
        }
    }

    /**
     * Metodilla voidaan päivittää linkin tiedot tietokantaan.
     *
     * @return boolean siitä, onnistuiko linkin paivittaminen tietokantaan.
     */
    public boolean updateLinkki() {
        Connection conn = null;
        PreparedStatement ps = null;

        boolean vastaus = true;

        try {
            conn = new Tietokanta().getYhteys();

            ps = conn.prepareStatement("" +
                    "UPDATE OPINTOPAIVAKIRJA.LINKKI " +
                    "SET OTSIKKO = ?, URL = ? " +
                    "WHERE ID = ?");
            ps.setString(1, this.otsikko);
            ps.setString(2, this.url);
            ps.setInt(3, this.id);

            ps.executeUpdate();

        } catch (SQLException ex) {
            Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
            vastaus = false;
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                    ps = null;
                } catch (SQLException ex) {
                    Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
                }
            }
            return vastaus;
        }
    }

    /**
     * Metodilla voidaan poistaa linkki tietokannasta.
     *
     * @return boolean siitä, onnistuiko linkin poistaminen tietokannasta.
     */
    public boolean deleteLinkki() {
        Connection conn = null;
        PreparedStatement ps = null;

        boolean vastaus = true;

        try {
            conn = new Tietokanta().getYhteys();

            ps = conn.prepareStatement("" +
                    "DELETE FROM OPINTOPAIVAKIRJA.LINKKI WHERE ID = ?");
            ps.setInt(1, this.id);

            ps.executeUpdate();

        } catch (SQLException ex) {
            Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
            vastaus = false;
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                    ps = null;
                } catch (SQLException ex) {
                    Virheenkasittely.getInstance().setVirhe(Tietokanta.class.getName(), ex);
                }
            }
            return vastaus;
        }
    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * @return the otsikko
     */
    public String getOtsikko() {
        return otsikko;
    }

    /**
     * @param otsikko the otsikko to set
     */
    public void setOtsikko(String otsikko) {
        this.otsikko = otsikko;
    }

    /**
     * @return the tila
     */
    public int getTila() {
        return tila;
    }

    /**
     * @param tila the tila to set
     */
    public void setTila(int tila) {
        this.tila = tila;
    }

    /**
     * @return the url
     */
    public String getUrl() {
        return url;
    }

    /**
     * @param url the url to set
     */
    public void setUrl(String url) {
        this.url = url;
    }
}

